//
//
//

#include "dlist.h"
#include <stdlib.h>

#include <stdio.h> // for debug

struct Node
{
    void *value;
    dlist pre;
    dlist next;
};

//
//
//
dlist
dl_create()
{
  //    printf("dl_create() start\n");
    dlist dl = (dlist)malloc(sizeof(struct Node));
    if (dl == NULL)
        return NULL;

    // init to NULL
    dl->value = NULL;
    dl->pre = NULL;
    dl->next = NULL;

    return dl;
}

//
//
//
void
dl_destroy(dlist dl)
{
  //    printf("dl_destroy() start\n");
    if (dl != NULL)
       free(dl);
    //    printf("%d is destroy\n", i);
}

//
//
//
void *
dl_add_after(dlist dl, void *value)
{
  //    printf("dl_add_after() start\n");
    if (dl == NULL)
        return NULL;

    // a new node
    dlist node = (dlist)malloc(sizeof(struct Node));
    if (node == NULL)
        return NULL;
    node->value = value;

    dlist nx = dl->next;
    if (nx != NULL) // not last
        nx->pre = node;
    node->next = nx;
    node->pre = dl;
    dl->next = node;

    return node;
}

//
//
//
void *
dl_remove_after(dlist dl)
{
  //    printf("dl_remove_after() start\n");
    dlist p = dl->next;
    if (p == NULL)
        return NULL;

    void *value = p->value;

    p->value = NULL;
    dlist nx = p->next;
    dlist pre = p->pre;

    // reset and dealloc
    p->next = NULL;
    p->pre = NULL;
    free(p);

    if (pre != NULL)
        pre->next = nx;
    if (nx != NULL)
        nx->pre = pre;
    return value;
}

//
//
//
dlist
dl_next(dlist dl)
{
    dlist next = dl->next;
    return next;
}

//
//
//
void *
dl_get_value(dlist dl)
{
  //    printf("dl_get_value() start\n");
    return dl->value;
}

//
//
//
void
dl_print(dlist start)
{
    printf("dl_print() start\n");
    // unimplemented

    dlist p = start;
    while (p != NULL) {
        printf("%d", p->value);
	p = dl_next(p);
    }
    printf("\n");
}

//
//
//
int
dl_foreach(dlist dl, DoSomeThingCB cb, void *ctx)
{
    printf("dl_() start\n");
    // unimplemented
    int ret = 0;

    dlist p = dl_next(dl);
    while ( p != NULL ) {
        ret = cb(p, ctx);
	if (ret == 0) {
	    return 0; // error on do someting
	}
	p = dl_next(p);
    }
    return 1;
}
